home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / rcs5ap1s.lzh / PARTIME.C < prev    next >
C/C++ Source or Header  |  1991-01-30  |  20KB  |  652 lines

  1. /*
  2.  * PARTIME        parse date/time string into a TM structure
  3.  *
  4.  * Returns:
  5.  *    0 if parsing failed
  6.  *    else time values in specified TM structure and zone (unspecified values
  7.  *        set to TMNULL)
  8.  * Notes:
  9.  *    This code is quasi-public; it may be used freely in like software.
  10.  *    It is not to be sold, nor used in licensed software without
  11.  *    permission of the author.
  12.  *    For everyone's benefit, please report bugs and improvements!
  13.  *     Copyright 1980 by Ken Harrenstien, SRI International.
  14.  *    (ARPANET: KLH @ SRI)
  15.  */
  16.  
  17. /* Hacknotes:
  18.  *    If parsing changed so that no backup needed, could perhaps modify
  19.  *        to use a FILE input stream.  Need terminator, though.
  20.  *    Perhaps should return 0 on success, else a non-zero error val?
  21.  */
  22.  
  23. /* $Log: partime.c,v $
  24.  * Revision 5.5  1991/01/30  14:21:32  apratt
  25.  * CI with RCS version 5
  26.  *
  27.  * Revision 5.4  90/10/04  06:30:15  eggert
  28.  * checked in with -k by apratt at 91.01.10.13.15.00.
  29.  * 
  30.  * Revision 5.4  1990/10/04  06:30:15  eggert
  31.  * Remove date vs time heuristics that fail between 2000 and 2400.
  32.  * Check for overflow when lexing an integer.
  33.  * Parse 'Jan 10 LT' as 'Jan 10, LT', not 'Jan, 10 LT'.
  34.  *
  35.  * Revision 5.3  1990/09/24  18:56:31  eggert
  36.  * Update timezones.
  37.  *
  38.  * Revision 5.2  1990/09/04  08:02:16  eggert
  39.  * Don't parse two-digit years, because it won't work after 1999/12/31.
  40.  * Don't permit 'Aug Aug'.
  41.  *
  42.  * Revision 5.1  1990/08/29  07:13:49  eggert
  43.  * Be able to parse our own date format.  Don't assume year<10000.
  44.  *
  45.  * Revision 5.0  1990/08/22  08:12:40  eggert
  46.  * Switch to GMT and fix the bugs exposed thereby.  Update timezones.
  47.  * Ansify and Posixate.  Fix peekahead and int-size bugs.
  48.  *
  49.  * Revision 1.4  89/05/01  14:48:46  narten
  50.  * fixed #ifdef DEBUG construct
  51.  * 
  52.  * Revision 1.3  88/08/28  14:53:40  eggert
  53.  * Remove unportable "#endif XXX"s.
  54.  * 
  55.  * Revision 1.2  87/03/27  14:21:53  jenkins
  56.  * Port to suns
  57.  * 
  58.  * Revision 1.1  82/05/06  11:38:26  wft
  59.  * Initial revision
  60.  * 
  61.  */
  62.  
  63. #include "rcsbase.h"
  64.  
  65. libId(partId, "$Id: partime.c,v 5.5 1991/01/30 14:21:32 apratt Exp $")
  66.  
  67. #define given(v) (0 <= (v))
  68. #define TMNULL (-1) /* Items not given are given this value */
  69. #define TZ_OFFSET (24*60) /* TMNULL  <  zone_offset - TZ_OFFSET */
  70.  
  71. struct tmwent {
  72.     const char *went;
  73.     short wval;
  74.     char wflgs;
  75.     char wtype;
  76. };
  77.     /* wflgs */
  78. #define TWTIME 02    /* Word is a time value (absence implies date) */
  79. #define TWDST  04    /* Word is a DST-type timezone */
  80.     /* wtype */
  81. #define TM_MON    1    /* month name */
  82. #define TM_WDAY    2    /* weekday name */
  83. #define TM_ZON    3    /* time zone name */
  84. #define TM_LT    4    /* local time */
  85. #define TM_DST    5    /* daylight savings time */
  86. #define TM_12    6    /* AM, PM, NOON, or MIDNIGHT */
  87.     /* wval (for wtype==TM_12) */
  88. #define T12_AM 1
  89. #define T12_PM 2
  90. #define T12_NOON 12
  91. #define T12_MIDNIGHT 0
  92.  
  93. static const struct tmwent tmwords [] = {
  94.     {"january",      0, 0, TM_MON},
  95.     {"february",     1, 0, TM_MON},
  96.     {"march",        2, 0, TM_MON},
  97.     {"april",        3, 0, TM_MON},
  98.     {"may",          4, 0, TM_MON},
  99.     {"june",         5, 0, TM_MON},
  100.     {"july",         6, 0, TM_MON},
  101.     {"august",       7, 0, TM_MON},
  102.     {"september",    8, 0, TM_MON},
  103.     {"october",      9, 0, TM_MON},
  104.     {"november",     10, 0, TM_MON},
  105.     {"december",     11, 0, TM_MON},
  106.  
  107.     {"sunday",       0, 0, TM_WDAY},
  108.     {"monday",       1, 0, TM_WDAY},
  109.     {"tuesday",      2, 0, TM_WDAY},
  110.     {"wednesday",    3, 0, TM_WDAY},
  111.     {"thursday",     4, 0, TM_WDAY},
  112.     {"friday",       5, 0, TM_WDAY},
  113.     {"saturday",     6, 0, TM_WDAY},
  114.  
  115.     {"gmt",          0*60, TWTIME, TM_ZON},   /* Greenwich */
  116.     {"utc",          0*60, TWTIME, TM_ZON},
  117.     {"ut",           0*60, TWTIME, TM_ZON},
  118.  
  119.     {"nzst",        -12*60, TWTIME, TM_ZON},  /* New Zealand */
  120.     {"jst",         -9*60, TWTIME, TM_ZON},   /* Japan */
  121.     {"kst",         -9*60, TWTIME, TM_ZON},   /* Korea */
  122.     {"ist",         -5*60-30, TWTIME, TM_ZON},/* India */
  123.     {"eet",         -2*60, TWTIME, TM_ZON},   /* Eastern Europe */
  124.     {"cet",         -1*60, TWTIME, TM_ZON},   /* Central Europe */
  125.     {"met",         -1*60, TWTIME, TM_ZON},   /* Middle Europe */
  126.     {"wet",          0*60, TWTIME, TM_ZON},   /* Western Europe */
  127.     {"nst",          3*60+30, TWTIME, TM_ZON},/* Newfoundland */
  128.     {"ast",          4*60, TWTIME, TM_ZON},   /* Atlantic */
  129.     {"est",          5*60, TWTIME, TM_ZON},   /* Eastern */
  130.     {"cst",          6*60, TWTIME, TM_ZON},   /* Central */
  131.     {"mst",          7*60, TWTIME, TM_ZON},   /* Mountain */
  132.     {"pst",          8*60, TWTIME, TM_ZON},   /* Pacific */
  133.     {"akst",         9*60, TWTIME, TM_ZON},   /* Alaska */
  134.     {"hast",         10*60, TWTIME, TM_ZON},  /* Hawaii-Aleutian */
  135.     {"hst",          10*60, TWTIME, TM_ZON},  /* Hawaii */
  136.     {"sst",          11*60, TWTIME, TM_ZON},  /* Samoa */
  137.  
  138.     {"nzdt",        -12*60, TWTIME+TWDST, TM_ZON},    /* New Zealand */
  139.     {"kdt",         -9*60, TWTIME+TWDST, TM_ZON},     /* Korea */
  140.     {"bst",          0*60, TWTIME+TWDST, TM_ZON},     /* Britain */
  141.     {"ndt",          2*60+30, TWTIME+TWDST, TM_ZON}, /*Newfoundland (DDST)*/
  142.     {"adt",          4*60, TWTIME+TWDST, TM_ZON},     /* Atlantic */
  143.     {"edt",          5*60, TWTIME+TWDST, TM_ZON},     /* Eastern */
  144.     {"cdt",          6*60, TWTIME+TWDST, TM_ZON},     /* Central */
  145.     {"mdt",          7*60, TWTIME+TWDST, TM_ZON},     /* Mountain */
  146.     {"pdt",          8*60, TWTIME+TWDST, TM_ZON},     /* Pacific */
  147.     {"akdt",         9*60, TWTIME+TWDST, TM_ZON},     /* Alaska */
  148.     {"hadt",         10*60, TWTIME+TWDST, TM_ZON},    /* Hawaii-Aleutian */
  149.  
  150. #if 0
  151.     /*
  152.      * The following names are duplicates or are not well attested.
  153.      * A standard is needed.
  154.      */
  155.     {"?st",         -13*60, TWTIME, TM_ZON},  /* Uelen */
  156.     {"?st",         -11*60, TWTIME, TM_ZON},  /* Magadan */
  157.     {"east",        -10*60, TWTIME, TM_ZON},  /* Eastern Australia */
  158.     {"cast",        -9*60-30, TWTIME, TM_ZON},/* Central Australia */
  159.     {"cst",         -8*60, TWTIME, TM_ZON},   /* China */
  160.     {"hkt",         -8*60, TWTIME, TM_ZON},   /* Hong Kong */
  161.     {"sst",         -8*60, TWTIME, TM_ZON},   /* Singapore */
  162.     {"wast",        -8*60, TWTIME, TM_ZON},   /* Western Australia */
  163.     {"?st",         -7*60, TWTIME, TM_ZON},   /* Novosibirsk */
  164.     {"jt",          -7*60-30, TWTIME, TM_ZON},/* Java */
  165.     {"nst",         -6*60-30, TWTIME, TM_ZON},/* North Sumatra */
  166.     {"?st",         -6*60, TWTIME, TM_ZON},   /* Tashkent */
  167.     {"?st",         -5*60, TWTIME, TM_ZON},      /* Sverdlovsk */
  168.     {"?",           -4*60-30, TWTIME, TM_ZON},/* Afghanistan */
  169.     {"?st",         -4*60, TWTIME, TM_ZON},      /* Rostov */
  170.     {"it",          -3*60-30, TWTIME, TM_ZON},/* Iran */
  171.     {"?st",         -3*60, TWTIME, TM_ZON},   /* Moscow */
  172.     {"ist",         -2*60, TWTIME, TM_ZON},   /* Israel */
  173.     {"ast",          1*60, TWTIME, TM_ZON},   /* Azores */
  174.     {"fst",          2*60, TWTIME, TM_ZON},   /* Fernando de Noronha */
  175.     {"bst",          3*60, TWTIME, TM_ZON},   /* Brazil */
  176.     {"wst",          4*60, TWTIME, TM_ZON},   /* Western Brazil */
  177.     {"ast",          5*60, TWTIME, TM_ZON},   /* Acre Brazil */
  178.     {"?",            9*60+30, TWTIME, TM_ZON},/* Marquesas */
  179.     {"?st",          12*60, TWTIME, TM_ZON},  /* Kwajalein */
  180.  
  181.     {"?dt",         -13*60, TWTIME+TWDST, TM_ZON},      /* Uelen */
  182.     {"?dt",         -11*60, TWTIME+TWDST, TM_ZON},      /* Magadan */
  183.     {"eadt",        -10*60, TWTIME+TWDST, TM_ZON},    /* Eastern Australia */
  184.     {"cadt",        -9*60-30, TWTIME+TWDST, TM_ZON},  /* Central Australia */
  185.     {"cdt",         -8*60, TWTIME+TWDST, TM_ZON},     /* China */
  186.     {"wadt",        -8*60, TWTIME+TWDST, TM_ZON},     /* Western Australia */
  187.     {"?dt",         -7*60, TWTIME+TWDST, TM_ZON},      /* Novosibirsk */
  188.     {"?dt",         -6*60, TWTIME+TWDST, TM_ZON},      /* Tashkent */
  189.     {"?dt",         -5*60, TWTIME+TWDST, TM_ZON},      /* Sverdlovsk */
  190.     {"?dt",         -4*60, TWTIME+TWDST, TM_ZON},      /* Rostov */
  191.     {"?dt",         -3*60, TWTIME+TWDST, TM_ZON},     /* Moscow */
  192.     {"idt",         -2*60, TWTIME+TWDST, TM_ZON},     /* Israel */
  193.     {"eest",        -2*60, TWTIME+TWDST, TM_ZON},     /* Eastern Europe */
  194.     {"cest",        -1*60, TWTIME+TWDST, TM_ZON},     /* Central Europe */
  195.     {"mest",        -1*60, TWTIME+TWDST, TM_ZON},     /* Middle Eur